package com.z.platform.controller.persistence.orm;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.z.platform.controller.persistence.ConnectionFactory;
import com.z.platform.controller.persistence.orm.annotation.Column;
import com.z.platform.controller.persistence.orm.annotation.Id;
import com.z.platform.controller.persistence.orm.annotation.Table;
import com.z.platform.controller.persistence.orm.metadataModel.Entity;
import com.z.ssmdemo.log.factory.ELogger;
import com.z.ssmdemo.log.factory.LogFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 21051
 */
public class JdbcDao extends AbstractDao {
    private static final ELogger LOG = LogFactory.getLog(JdbcDao.class);

    @Override
    public int insert(Entity entity) {
        Class<? extends Entity> entityClass = entity.getClass();
        Table table = entityClass.getAnnotation(Table.class);
        //
        String tableName = table.tableName();
        if (Strings.isNullOrEmpty(tableName)) {
            throw new RuntimeException("");
        }
        StringJoiner columnKeys = new StringJoiner(", ", "(", ")");
        StringJoiner columnValues = new StringJoiner(", ", "(", ")");
        StringJoiner placeholder = new StringJoiner(", ", "(", ")");
        ConcurrentMap<Integer, String> valueConcurrentMap = Maps.newConcurrentMap();
        ConcurrentMap<Integer, String> typeConcurrentMap = Maps.newConcurrentMap();
        AtomicInteger index = new AtomicInteger(0);
        Arrays.stream(entityClass.getDeclaredFields()).filter(itemField -> {
            Id id = itemField.getAnnotation(Id.class);
            if (Objects.nonNull(id)) {
                return !Strings.isNullOrEmpty(id.priMaryKey());
            }
            Column fieldAnnotation = itemField.getAnnotation(Column.class);
            if (Objects.nonNull(fieldAnnotation)) {
                return !Strings.isNullOrEmpty(fieldAnnotation.column());
            }
            return false;
        }).forEach(notNullItemField -> {
            try {
                notNullItemField.setAccessible(true);
                Object columnValue = notNullItemField.get(entity);
                Id id = notNullItemField.getAnnotation(Id.class);
                Column notNullItemFieldAnnotation = notNullItemField.getAnnotation(Column.class);
                if (Objects.nonNull(columnValue) && Objects.nonNull(id)) {
                    //获取属性上的指定注解的值，进行拼接
                    columnKeys.add("`" + id.priMaryKey() + "`");
                    //预编译用的
                    placeholder.add("?");
                    //封装对应列表的值  可能没什么用
                    columnValues.add(columnValue.toString());
                    //封装庶预编译的值 分装成 map 后面要用
                    //主键的key是0
                    valueConcurrentMap.putIfAbsent(index.incrementAndGet(), UUID.randomUUID().toString());
                    typeConcurrentMap.put(index.get(), notNullItemField.getType().getName());
                }
                //if ( !Strings.isNullOrEmpty(columnValue.toString()) ){
                if (Objects.nonNull(columnValue) && Objects.nonNull(notNullItemFieldAnnotation)) {
                    //获取属性上的指定注解的值，进行拼接
                    columnKeys.add("`" + notNullItemFieldAnnotation.column() + "`");
                    //预编译用的
                    placeholder.add("?");
                    //封装对应列表的值  可能没什么用
                    columnValues.add(columnValue.toString());
                    //封装庶预编译的值 分装成 map 后面要用
                    valueConcurrentMap.putIfAbsent(index.incrementAndGet(), columnValue.toString());
                    typeConcurrentMap.put(index.get(), notNullItemField.getType().getName());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
        //INSERT INTO `java_demo`.`DEMO_USER` (`id`, `pazz_word`, `nick_name`, `Name`, `Sex`, `Reg_date`, `Brith_date`) VALUES ('03689720-7b65-4d28-9f7f-2fbba519eb12', '123456', '张豪楠', '张豪楠', NULL, NULL, NULL);
        String sql = " INSERT INTO `java_demo`." + "`" + tableName + "`" + columnKeys.toString() +
                " VALUES " + placeholder.toString();
        LOG.info("插入的sql语句是{}", sql);
        JdbcConnectionModel jdbcConnectionModel = this.getInsertPreparedStatement(sql, valueConcurrentMap, typeConcurrentMap);

        try {
            return jdbcConnectionModel.getPreparedStatement().executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            this.jdbcShoutDown(jdbcConnectionModel);
        }
        return 0;
    }

    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        //UPDATE `java_demo`.`DEMO_USER` SET `pazz_word` = '123456d777' WHERE `id` = 'c2a741bd-6268-4094-a962-0f759d840546'
        String sql = " UPDATE `java_demo`.`DEMO_USER` SET  pazz_word = ? WHERE id = ?;";
        try {
            conn = ConnectionFactory.getConnection();
             preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setString(1, "123456d776");
            preparedStatement.setString(2, "c2a741bd-6268-4094-a962-0f759d840546");
            int i = preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            conn.close();
            preparedStatement.close();
        }
    }

    @Override
    public int updateById(Entity entity) {
        return 0;
    }

    @Override
    public int delete(Entity entity) {
        return 0;
    }

    @Override
    public List<Map<String, Object>> select(String sql, Object... params) {
        return null;
    }

    @Override
    public void startTransaction() {

    }

    @Override
    public void commitTransaction() {

    }

    @Override
    public void rollbackTransaction() {

    }
}
